/** SimpleServer12.java:
 * 	This server serves only one client connection.
 * 	*/

import java.io.*;
import java.net.*;
import java.util.*;

public class SimpleServer12 {

    public static void main(String arg[]){

	try {
	   ServerSocket  ssk = new ServerSocket(9912);
	   Socket 	sk = null;
	   Thread	agent = null;
	   int		nextID = 0;
	   BroadCaster bc = new BroadCaster();

	   while ( true ) {
	       System.out.printf("Connections made %d, Listening for more ... \n", nextID);
	       sk = ssk.accept ();
	       agent = new Thread( new Agent( ++ nextID, sk, bc ) );
	       agent.start();
	   }
	} catch (IOException e) { }
    }
}

class Agent implements Runnable {
   InputStream		reader= null;
   OutputStream		writer = null;
   Socket		sk = null;
   byte			buf[] = new byte[200];
   String		msg = null;
   int			ID, msgCount = 0;
   BroadCaster		bc = null;
   public Agent ( int id, Socket s, BroadCaster c ) {
       try {
	   ID = id; sk = s;
	   reader = sk.getInputStream();
	   writer = sk.getOutputStream();
	   bc     = c;
	   bc.add( writer);
	} catch (IOException e) {}
   }

   public void run() {
     int	k = 0;
     try {
	while ( true ) {
	   k = reader.read(buf); 
	   bc.broadcast(buf, 0, k);
	 } 
     }
     catch(Exception e) { bc.remove(writer);
	 try { sk.close(); } catch (IOException f) {}  } 
   }
}

class BroadCaster {
    Vector<OutputStream> vec = new Vector<OutputStream>();
    synchronized public void add(OutputStream out ) {
	vec.add(out);
    }
    synchronized public void remove(OutputStream out) {
	vec.remove(out);
    }

    synchronized public void broadcast( byte buf[], int start, int len) {
	Iterator<OutputStream> itr = vec.iterator();
	while ( itr.hasNext() ) {
	   try {
	       	itr.next().write(buf, start, len);
	   } catch (Exception e) { }
	}
    }
}
